home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / bc_pas_1.zip / CDROM.C < prev    next >
C/C++ Source or Header  |  1992-09-15  |  14KB  |  801 lines

  1. ;    /*\
  2. ;    |*|    cdrom.c
  3. ;    |*|    
  4. ;    |*|    routines for c-interface to mscdex audio functions
  5. ;    |*|
  6. ;    |*|    Copyright (c) 1992, Media Vision, Inc.  All Rights Reserved
  7. ;    |*|
  8. ;    \*/
  9.  
  10. #include "cdrom.h"
  11.  
  12. static int OURDISCSTATUS[26];
  13.  
  14. ;    /*\
  15. ;    |*|    cdplay(int drive, long frame, long lframe)
  16. ;    |*|
  17. ;    |*|    begin audio play on drive from frame for lframe frames
  18. ;    |*|
  19. ;    |*|    Entry:    drive number, starting frame, count of frames to play
  20. ;    |*|
  21. ;    |*|    Exit:    return driver status
  22. ;    |*|
  23. ;    \*/
  24.  
  25. cdplay(int drive, long frame, long lframe)
  26. {
  27.     struct ioctlplay iop;
  28.  
  29.     iop.cdh.len= 13;
  30.     iop.cdh.unit= (char) drive;
  31.     iop.cdh.cmd= CD_CMD_PLAY;
  32.     iop.cdh.stat= 0;
  33.  
  34.     iop.addrmode= 0;
  35.     iop.startsector= frame- 150;
  36.     iop.sectorcount= lframe;
  37.  
  38.     senddevreq(drive, &iop);
  39.  
  40.     if (!(iop.cdh.stat& 0x8000) || (iop.cdh.stat& 0x0100))
  41.         {
  42.         OURDISCSTATUS[drive]|= CDISPLAYING;
  43.         OURDISCSTATUS[drive]&= (-1^ CDISPAUSED);
  44.         }
  45.  
  46.     return(iop.cdh.stat);
  47. }
  48.  
  49. ;    /*\
  50. ;    |*|    cdstop(int drive)
  51. ;    |*|
  52. ;    |*|    stop audio play on drive
  53. ;    |*|
  54. ;    |*|    Entry:    drive number
  55. ;    |*|
  56. ;    |*|    Exit:    return driver status
  57. ;    |*|
  58. ;    \*/
  59.  
  60. cdstop(int drive)
  61. {
  62.     struct ioctlstop ios;
  63.  
  64.     if (cdstatus(drive)& CDISPLAYING)
  65.         cdpause(drive);
  66.  
  67.     ios.cdh.len= 13;
  68.     ios.cdh.unit= (char) drive;
  69.     ios.cdh.cmd= CD_CMD_STOP;
  70.     ios.cdh.stat= 0;
  71.  
  72.     senddevreq(drive, &ios);
  73.  
  74.     if (!(ios.cdh.stat& 0x8000) || (ios.cdh.stat& 0x0100))
  75.         {
  76.         OURDISCSTATUS[drive]&= (-1^ (CDISPAUSED| CDISPLAYING));
  77.         }
  78.  
  79.     return(ios.cdh.stat);
  80. }
  81.  
  82. ;    /*\
  83. ;    |*|    cdpause(int drive)
  84. ;    |*|
  85. ;    |*|    pause audio play on drive
  86. ;    |*|
  87. ;    |*|    Entry:    drive number
  88. ;    |*|
  89. ;    |*|    Exit:    return 0 if not playing, else return driver status
  90. ;    |*|
  91. ;    \*/
  92.  
  93. cdpause(int drive)
  94. {
  95.     struct ioctlstop ios;
  96.  
  97.     if (!(cdstatus(drive)& CDISPLAYING))
  98.         return(0);
  99.  
  100.     ios.cdh.len= 13;
  101.     ios.cdh.unit= (char) drive;
  102.     ios.cdh.cmd= CD_CMD_STOP;
  103.     ios.cdh.stat= 0;
  104.  
  105.     senddevreq(drive, &ios);
  106.  
  107.     if (!(ios.cdh.stat& 0x8000))
  108.         {
  109.         OURDISCSTATUS[drive]|= CDISPAUSED;
  110.         OURDISCSTATUS[drive]&= (-1^ CDISPLAYING);
  111.         }
  112.  
  113.     return(ios.cdh.stat);
  114. }
  115.  
  116. ;    /*\
  117. ;    |*|    cdresume(int drive)
  118. ;    |*|
  119. ;    |*|    resume paused audio play on drive
  120. ;    |*|
  121. ;    |*|    Entry:    drive number
  122. ;    |*|
  123. ;    |*|    Exit:    return driver status
  124. ;    |*|
  125. ;    \*/
  126.  
  127. cdresume(int drive)
  128. {
  129.     struct ioctlresume ior;
  130.  
  131.     ior.cdh.len= 13;
  132.     ior.cdh.unit= (char) drive;
  133.     ior.cdh.cmd= CD_CMD_RESUME;
  134.     ior.cdh.stat= 0;
  135.  
  136.     senddevreq(drive, &ior);
  137.  
  138.     if (!(ior.cdh.stat& 0x8000))
  139.         {
  140.         if ((cdstatus(drive)& CDISPLAYING))
  141.             OURDISCSTATUS[drive]|= CDISPLAYING;
  142.         OURDISCSTATUS[drive]&= (-1^ CDISPAUSED);
  143.         }
  144.  
  145.     return(ior.cdh.stat);
  146. }
  147.  
  148. ;    /*\
  149. ;    |*|    cdseek(int drive, long frame)
  150. ;    |*|
  151. ;    |*|    move head on drive to specified frame
  152. ;    |*|
  153. ;    |*|    Entry:    drive number, frame number
  154. ;    |*|
  155. ;    |*|    Exit:    return driver status
  156. ;    |*|
  157. ;    \*/
  158.  
  159. cdseek(int drive, long frame)
  160. {
  161.     struct ioctlseek ios;
  162.  
  163.     ios.cdh.len= 13;
  164.     ios.cdh.unit= (char) drive;
  165.     ios.cdh.cmd= CD_CMD_SEEK;
  166.     ios.cdh.stat= 0;
  167.  
  168.     ios.addrmode= 0;
  169.     ios.buffer= (void far *) 0;
  170.     ios.sectorcount= 0;
  171.     ios.startsector= frame- 150;
  172.  
  173.     senddevreq(drive, &ios);
  174.  
  175.     if (!(ios.cdh.stat& 0x8000))
  176.         {
  177.         OURDISCSTATUS[drive]&= (-1^ (CDISPLAYING| CDISPAUSED));
  178.         }
  179.  
  180.     return(ios.cdh.stat);
  181. }
  182.  
  183. ;    /*\
  184. ;    |*|    cdreset(int drive)
  185. ;    |*|
  186. ;    |*|    reset the driver for specified drive
  187. ;    |*|
  188. ;    |*|    Entry:    drive number
  189. ;    |*|
  190. ;    |*|    Exit:    return driver status
  191. ;    |*|
  192. ;    \*/
  193.  
  194. cdreset(int drive)
  195. {
  196.     struct ioctlwrite iow;
  197.     char dummy= CD_CMD_RESET;
  198.  
  199.     iow.cdh.len= 13;
  200.     iow.cdh.unit= (char) drive;
  201.     iow.cdh.cmd= IOCTL_WRITE;
  202.     iow.cdh.stat= 0;
  203.  
  204.     iow.mdb= 0;
  205.     iow.buffer= (void far *) &dummy;
  206.     iow.size= sizeof(dummy);
  207.     iow.ssn= 0;
  208.     iow.errbuf= (void far *) 0;
  209.  
  210.     senddevreq(drive, &iow);
  211.  
  212.     if (!(iow.cdh.stat& 0x8000))
  213.         OURDISCSTATUS[drive]&= (-1^ (CDISPAUSED| CDISPLAYING| CDISHERE));
  214.  
  215.     return(iow.cdh.stat);
  216. }
  217.  
  218. ;    /*\
  219. ;    |*|    cdeject(int drive)
  220. ;    |*|
  221. ;    |*|    eject disc in drive
  222. ;    |*|
  223. ;    |*|    Entry:    drive number
  224. ;    |*|
  225. ;    |*|    Exit:    return driver status
  226. ;    |*|
  227. ;    \*/
  228.  
  229. cdeject(int drive)
  230. {
  231.     struct ioctlwrite iow;
  232.     char dummy= CD_CMD_EJECT;
  233.  
  234.     iow.cdh.len= 13;
  235.     iow.cdh.unit= (char) drive;
  236.     iow.cdh.cmd= IOCTL_WRITE;
  237.     iow.cdh.stat= 0;
  238.  
  239.     iow.mdb= 0;
  240.     iow.buffer= (void far *) &dummy;
  241.     iow.size= sizeof(dummy);
  242.     iow.ssn= 0;
  243.     iow.errbuf= (void far *) 0;
  244.  
  245.     senddevreq(drive, &iow);
  246.  
  247.     if (!(iow.cdh.stat& 0x8000))
  248.         OURDISCSTATUS[drive]&= (-1^ (CDISPAUSED| CDISPLAYING| CDISHERE));
  249.  
  250.     return(iow.cdh.stat);
  251. }
  252.  
  253. ;    /*\
  254. ;    |*|    cdstatus(int drive)
  255. ;    |*|
  256. ;    |*|    get audio status of drive number, update internal status variable
  257. ;    |*|
  258. ;    |*|    Entry:    drive number
  259. ;    |*|
  260. ;    |*|    Exit:    internal status variable
  261. ;    |*|
  262. ;    \*/
  263.  
  264. cdstatus(int drive)
  265. {
  266.     int status= 0;
  267.     long d1, d2;
  268.  
  269.     status= cdaudiostatus(drive, &d1, &d2);
  270.  
  271.     return(OURDISCSTATUS[drive]);
  272. }
  273.  
  274. ;    /*\
  275. ;    |*|    cdaudiostatus(int drive, long *nextstart, long *nextend)
  276. ;    |*|
  277. ;    |*|    get audio status of drive number, update internal status variable
  278. ;    |*|
  279. ;    |*|    Entry:    drive number, pointers to nextstart and nextend frames
  280. ;    |*|
  281. ;    |*|    Exit:    return driver status
  282. ;    |*|
  283. ;    \*/
  284.  
  285. cdaudiostatus(int drive, long *nextstart, long *nextend)
  286. {
  287.     int status= 0;
  288.     struct ioctlread ior;
  289.     struct ioctlstat ios;
  290.     struct qchaninfo sqi;
  291.  
  292.     cdqchaninfo(drive, &sqi);
  293.  
  294.     ior.cdh.len= 13;
  295.     ior.cdh.unit= (char) drive;
  296.     ior.cdh.cmd= IOCTL_READ;
  297.     ior.cdh.stat= 0;
  298.  
  299.     ior.mdb= 0;
  300.     ior.buffer= (void far *) &ios;
  301.     ior.size= sizeof(ios);
  302.     ior.ssn= 0;
  303.     ior.errbuf= (void far *) 0;
  304.  
  305.     ios.cmd= 15;
  306.     ios.status= 0;
  307.     ios.startloc= 0;
  308.     ios.endloc= 0;
  309.  
  310.     senddevreq(drive, &ior);
  311.  
  312.     if (ior.cdh.stat& 0x0200)    status|= CDISPLAYING;
  313.     if (ios.status& 0x0001)     status|= CDISPAUSED;
  314.  
  315.     OURDISCSTATUS[drive]&= CDISHERE;
  316.     if (OURDISCSTATUS[drive]& CDISHERE)
  317.         if (!status)
  318.             {
  319.             int i= 0;
  320.             long d;
  321.             long s;
  322.             struct qchaninfo dqi;
  323.             s= msftolong(* ((long *) &sqi.min));
  324.  
  325.             do
  326.                 {
  327.                 long *pd= (long *) &dqi.min;
  328.                 cdqchaninfo(drive, &dqi);
  329.                 d= msftolong(*pd);
  330.                 }
  331.             while (++i < 5 && d - s < 75);
  332.  
  333.             if (i < 5)     status|= CDISPLAYING;
  334.             }
  335.  
  336.     OURDISCSTATUS[drive]|= status;
  337.  
  338.     *nextstart= ios.startloc;
  339.     *nextend= ios.endloc;
  340.  
  341.     return(ios.status);
  342. }
  343.  
  344. ;    /*\
  345. ;    |*|    cdmediachanged(int drive, int *yesorno)
  346. ;    |*|
  347. ;    |*|    check if media has changed for drive
  348. ;    |*|
  349. ;    |*|    Entry:    drive number, pointer to flag
  350. ;    |*|
  351. ;    |*|    Exit:    return 0 if successful, else return -1 if error occurred
  352. ;    |*|
  353. ;    \*/
  354.  
  355. cdmediachanged(int drive, int *yesorno)
  356. {
  357.     int status= 0;
  358.     struct ioctlread ior;
  359.     struct {
  360.         char cmd;
  361.         char changed;
  362.         } dummy;
  363.  
  364.     ior.cdh.len= sizeof(struct cdreqheader);
  365.     ior.cdh.unit= (char) drive;
  366.     ior.cdh.cmd= IOCTL_READ;
  367.     ior.cdh.stat= 0;
  368.     
  369.     ior.mdb= 0;
  370.     ior.buffer= (void far *) &dummy;
  371.     ior.size= sizeof(dummy);
  372.     ior.ssn= 0;
  373.     ior.errbuf= (void far *) 0;
  374.  
  375.     dummy.cmd= 9;
  376.     dummy.changed= 0;
  377.  
  378.     senddevreq(drive, &ior);
  379.     status= ior.cdh.stat;
  380.  
  381.     if (status& 0x8000)
  382.         return(-1);
  383.  
  384.     *yesorno= dummy.changed;
  385.  
  386.     return(0);
  387. }
  388.  
  389. ;    /*\
  390. ;    |*|    int cddiscinfo(int drive, struct discinfo *di)
  391. ;    |*|
  392. ;    |*|    get information on disc in drive
  393. ;    |*|
  394. ;    |*|    Entry:    drive number, address of buffer
  395. ;    |*|
  396. ;    |*|    Exit:    return driver status
  397. ;    |*|
  398. ;    \*/
  399.  
  400. int cddiscinfo(int drive, struct discinfo *di)
  401. {
  402.     int status= 0;
  403.     struct ioctlread ior;
  404.  
  405.     ior.cdh.len= sizeof(struct cdreqheader);
  406.     ior.cdh.unit= (char) drive;
  407.     ior.cdh.cmd= IOCTL_READ;
  408.     ior.cdh.stat= 0;
  409.  
  410.     ior.mdb= 0;
  411.     ior.buffer= (void far *) di;
  412.     ior.size= sizeof(struct discinfo);
  413.     ior.ssn= 0;
  414.     ior.errbuf= (void far *) 0;
  415.  
  416.     di->cmd= CD_GETDISCINFO;
  417.     di->strk= 0;
  418.     di->ltrk= 0;
  419.     di->eodisc= 0;
  420.  
  421.     senddevreq(drive, &ior);
  422.     status= ior.cdh.stat;
  423.  
  424.     if (status& 0x8000 || !(status& 0x0100))
  425.         OURDISCSTATUS[drive]&= (-1^ CDISHERE);
  426.     else
  427.         OURDISCSTATUS[drive]|= CDISHERE;
  428.  
  429.     return(status);
  430. }
  431.  
  432. ;    /*\
  433. ;    |*|    int cdtrackinfo(int drive, int track, struct trackinfo *ti)
  434. ;    |*|
  435. ;    |*|    get information on track of disc in drive
  436. ;    |*|
  437. ;    |*|    Entry:    drive number, track number, address of buffer
  438. ;    |*|
  439. ;    |*|    Exit:    return driver status
  440. ;    |*|
  441. ;    \*/
  442.  
  443. int cdtrackinfo(int drive, int track, struct trackinfo *ti)
  444. {
  445.     int status= 0;
  446.     struct ioctlread ior;
  447.  
  448.     ior.cdh.len= 13;
  449.     ior.cdh.unit= (char) drive;
  450.     ior.cdh.cmd= IOCTL_READ;
  451.     ior.cdh.stat= 0;
  452.  
  453.     ior.mdb= 0;
  454.     ior.buffer= (void far *) ti;
  455.     ior.size= sizeof(struct trackinfo);
  456.     ior.ssn= 0;
  457.     ior.errbuf= (void far *) 0;
  458.  
  459.     ti->cmd= CD_GETTRACKINFO;
  460.     ti->track= (char) track;
  461.     ti->min= 0;
  462.     ti->sec= 0;
  463.     ti->frame= 0;
  464.     ti->control= 0;
  465.  
  466.     senddevreq(drive, &ior);
  467.     status|= ior.cdh.stat;
  468.  
  469.     return(status);
  470. }
  471.  
  472.  
  473. ;    /*\
  474. ;    |*|    int cdqchaninfo(int drive, struct qchaninfo *qi)
  475. ;    |*|
  476. ;    |*|    get status from q-channel for drive
  477. ;    |*|
  478. ;    |*|    Entry:    drive number, address of buffer
  479. ;    |*|
  480. ;    |*|    Exit:    return driver status
  481. ;    |*|
  482. ;    \*/
  483.  
  484. int cdqchaninfo(int drive, struct qchaninfo *qi)
  485. {
  486.     int status= 0;
  487.     struct ioctlread ior;
  488.  
  489.     ior.cdh.len= sizeof(struct cdreqheader);
  490.     ior.cdh.unit= (char) drive;
  491.     ior.cdh.cmd= IOCTL_READ;
  492.     ior.cdh.stat= 0;
  493.  
  494.     ior.mdb= 0;
  495.     ior.buffer= (void far *) qi;
  496.     ior.size= sizeof(struct qchaninfo);
  497.     ior.ssn= 0;
  498.     ior.errbuf= (void far *) 0;
  499.  
  500.     qi->cmd= CD_GETQCHANINFO;
  501.     qi->caa= 0;
  502.     qi->track= 0;
  503.     qi->index= 0;
  504.     qi->min= 0;
  505.     qi->sec= 0;
  506.     qi->frame= 0;
  507.     qi->reserved1= 0;
  508.     qi->amin= 0;
  509.     qi->asec= 0;
  510.     qi->aframe= 0;
  511.  
  512.     senddevreq(drive, &ior);
  513.     status= ior.cdh.stat;
  514.  
  515.     if (status& 0x8000 || !(status& 0x0100))
  516.         OURDISCSTATUS[drive]&= (-1^ CDISHERE);
  517.     else
  518.         OURDISCSTATUS[drive]|= CDISHERE;
  519.  
  520.     return(status);
  521. }
  522.  
  523. ;    /*\
  524. ;    |*|    isanaudiocd(int drive)
  525. ;    |*|
  526. ;    |*|    check if disc in drive is an audio cd
  527. ;    |*|
  528. ;    |*|    Entry:    drive number
  529. ;    |*|
  530. ;    |*|    Exit:    return 1 if is an audio cd, else return 0
  531. ;    |*|
  532. ;    \*/
  533.  
  534. isanaudiocd(int drive)
  535. {
  536.     int failcount= 0;
  537.     struct discinfo di;
  538.  
  539.     do
  540.         {
  541.         if (!((cddiscinfo(drive, &di))& 0x8000))
  542.             return(1);
  543.         }
  544.     while (++failcount < 5);
  545.  
  546.     return(0);
  547.  
  548. }
  549.  
  550. ;    /*\
  551. ;    |*|    cdseekmsf(int drive, int min, int sec, int frame)
  552. ;    |*|
  553. ;    |*|    move head on drive to frame specified by min:sec:frame
  554. ;    |*|
  555. ;    |*|    Entry:    drive number, minutes, seconds, frames
  556. ;    |*|
  557. ;    |*|    Exit:    return driver status
  558. ;    |*|
  559. ;    \*/
  560.  
  561. cdseekmsf(int drive, int min, int sec, int frame)
  562. {
  563.     long f;
  564.  
  565.     f= (long) min* 60;
  566.     f+= (long) sec;
  567.     f*= (long) 75;
  568.     f+= (long) frame;
  569.  
  570.     return(cdseek(drive, f));
  571. }
  572.  
  573. ;    /*\
  574. ;    |*|    cdplaymsf(int drive, int min, int sec, int frame, int lmin, int lsec, int lframe)
  575. ;    |*|
  576. ;    |*|    begin play for drive according at min:sec:frame for min:sec:frame
  577. ;    |*|
  578. ;    |*|    Entry:    drive number, minutes:seconds:frames to start and
  579. ;    |*|                minutes:seconds:frames for length
  580. ;    |*|
  581. ;    |*|    Exit:    return driver status
  582. ;    |*|
  583. ;    \*/
  584.  
  585. cdplaymsf(int drive, int min, int sec, int frame, int lmin, int lsec, int lframe)
  586. {
  587.     long f;
  588.     long lf;
  589.  
  590.     f= (long) min* 60;
  591.     f+= (long) sec;
  592.     f*= (long) 75;
  593.     f+= (long) frame;
  594.     lf= (long) lmin* 60;
  595.     lf+= (long) lsec;
  596.     lf*= (long) 75;
  597.     lf+= (long) lframe;
  598.  
  599.     return(cdplay(drive, f, lf));
  600. }
  601.  
  602. ;    /*\
  603. ;    |*|    long redtolong(long redaddress)
  604. ;    |*|
  605. ;    |*|    convert redbook address to frame number
  606. ;    |*|
  607. ;    |*|    Entry:    redbook address (0x00MMSSFF)
  608. ;    |*|
  609. ;    |*|    Exit:    frame number
  610. ;    |*|
  611. ;    \*/
  612.  
  613. long redtolong(long redaddress)
  614. {
  615.     long longval= 0;
  616.     union 
  617.         {
  618.         struct {
  619.             char frame;
  620.             char sec;
  621.             char min;
  622.             char dead;
  623.             } rtl;
  624.         long l;
  625.         } d;
  626.  
  627.     d.l= redaddress;
  628.  
  629.     longval+= d.rtl.min;
  630.     longval*= 60;
  631.     longval+= d.rtl.sec;
  632.     longval*= 75;
  633.     longval+= d.rtl.frame;
  634.  
  635.     return(longval);
  636. }
  637.  
  638.  
  639. ;    /*\
  640. ;    |*|    long longtored(long longval)
  641. ;    |*|
  642. ;    |*|    convert frame number to redbook address   
  643. ;    |*|
  644. ;    |*|    Entry:    frame value 
  645. ;    |*|
  646. ;    |*|    Exit:        redbook address (0x00MMSSFF)
  647. ;    |*|
  648. ;    \*/
  649.  
  650. long longtored(long longval)
  651. {
  652.     union 
  653.         {
  654.         struct {
  655.             char frame;
  656.             char sec;
  657.             char min;
  658.             char dead;
  659.             } rtl;
  660.         long l;
  661.         } d;
  662.  
  663.     d.rtl.min= longval/ 4500;
  664.     d.rtl.sec= (longval% 4500)/ 75;
  665.     d.rtl.frame= (longval% 4500)% 75;
  666.  
  667.     return(d.l);
  668. }
  669.  
  670. ;    /*\
  671. ;    |*|    long msftolong(long msfvalue)
  672. ;    |*|
  673. ;    |*|    convert FFSSMM00 value to frame number
  674. ;    |*|
  675. ;    |*|    Entry:    msf value (0xFFSSMM00)
  676. ;    |*|
  677. ;    |*|    Exit:    frame number
  678. ;    |*|
  679. ;    \*/
  680.  
  681. long msftolong(long msfvalue)
  682. {
  683.     long longval= 0;
  684.     union 
  685.         {
  686.         struct {
  687.             char min;
  688.             char sec;
  689.             char frame;
  690.             char dead;
  691.             } mtl;
  692.         long l;
  693.         } d;
  694.  
  695.     d.l= msfvalue;
  696.  
  697.     longval+= d.mtl.min;
  698.     longval*= 60;
  699.     longval+= d.mtl.sec;
  700.     longval*= 75;
  701.     longval+= d.mtl.frame;
  702.  
  703.     return(longval);
  704. }
  705.  
  706. ;    /*\
  707. ;    |*|    inttobcd(int data)
  708. ;    |*|
  709. ;    |*|    convert an integer to BCD representation
  710. ;    |*|
  711. ;    |*|    Entry:    integer
  712. ;    |*|
  713. ;    |*|    Exit:    value as BCD
  714. ;    |*|
  715. ;    \*/
  716.  
  717. inttobcd(int data)
  718. {
  719.     int val;
  720.  
  721.     val= (data/ 10)<< 4;
  722.     val+= (data% 10);
  723.  
  724.     return(val);
  725. }
  726.  
  727. ;    /*\
  728. ;    |*|    bcdtoint(int data)
  729. ;    |*|
  730. ;    |*|    convert a BCD number to an integer
  731. ;    |*|
  732. ;    |*|    Entry:    BCD number
  733. ;    |*|
  734. ;    |*|    Exit:    integer value
  735. ;    |*|
  736. ;    \*/
  737.  
  738. bcdtoint(int data)
  739. {
  740.     int val;
  741.  
  742.     val= data& 0x0F;
  743.     val+= ((data&0xF0)>> 4)* 10;
  744.  
  745.     return(val);
  746. }
  747.  
  748. ;    /*\
  749. ;    |*|    fixmsf(int *min, int *sec, int *frame)
  750. ;    |*|
  751. ;    |*|    boundarize elements of msf number
  752. ;    |*|
  753. ;    |*|    Entry:    int pointers to minutes, seconds and frame variables
  754. ;    |*|
  755. ;    |*|    Exit:    return -1 if minute ends up negative, 0 if not and
  756. ;    |*|            affect pointed to numbers
  757. ;    |*|
  758. ;    \*/
  759.  
  760. fixmsf(int *min, int *sec, int *frame)
  761. {
  762.     int f= *frame;
  763.     int s= *sec;
  764.     int m= *min;
  765.  
  766.     while (f >= 75)
  767.         {
  768.         f-= 75;
  769.         s+= 1;
  770.         }
  771.  
  772.     while (s >= 60)
  773.         {
  774.         s-= 60;
  775.         m+= 1;
  776.         }
  777.  
  778.     while (f < 0)
  779.         {
  780.         f+= 75;
  781.         s-= 1;
  782.         }
  783.  
  784.     while (s < 0)
  785.         {
  786.         s+= 60;
  787.         m-= 1;
  788.         }
  789.  
  790.     if (m < 0)
  791.         return(-1);
  792.  
  793.     *frame= f;
  794.     *sec= s;
  795.     *min= m;
  796.  
  797.     return(0);
  798. }
  799.  
  800.  
  801.